#include "hhash.h"
#include "tpool.h"
#include "tse.h"
#include "cpool.h"

#define STOCKNO 2000
#define	NUM_worker	100
#define	MAX_queue	100
#define	PORT	10000
#define	GROUP	"224.0.100.100"
#define	LOGPATH	"/export/home/stock/log"

tpool_t fnDecodepool;
static void daemon_init();
static void h_read();
static void h_watchdog();
static void h_shm_tpool_init();
static void fatal( register char const *const fmt, register char const *const arg );

static void fatal( register char const *const fmt, register char const *const arg )
{
	lprintf(log, FATAL, (void *) fmt, (void *) arg );
	exit (1);
}

static void 
h_shm_tpool_init()
{
        time_t tp,t;
        struct tm tmstr;
        char szLog[20];
  
        t = time( &tp );
        tmstr = *localtime( &t );
        sprintf( gszdate, "%04d%02d%02d", tmstr.tm_year+1900, tmstr.tm_mon+1, tmstr.tm_mday );
        
        sprintf( szLog, "%s/TSEERR.log", LOGPATH );
        log=log_open( szLog, 0);
        
        sprintf( szLog, "%s/TSECPOOL.log", LOGPATH ); 
        flog=log_open( szLog, 0 ); 
 
        cpool_init();  //init connect pool
        SHM_init( (key_t) 1101); // otc first num
      
        hcreate( STOCKNO );
        tpool_init( &fnDecodepool, NUM_worker, MAX_queue, 0); 
        strcpy( ltick->date, gszdate); lprintf(log, INFO, "init ok!!\n");
}

static void
h_read()
{
        int  sockfd, cnt, len_r;
        char recvbuf[MAX_BUF_SIZE];
        char *buf;
        struct sockaddr_in addr;
        struct ip_mreq imr;
        
        h_shm_tpool_init();
        if (( sockfd = socket ( PF_INET, SOCK_DGRAM, 0 )) == -1)
        	fatal ("Error creating socket: %s\n", strerror (errno));
	
        memset( &addr, 0, sizeof(addr) );
        addr.sin_family=AF_INET;
        addr.sin_port=htons(PORT);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);

	if ( bind ( sockfd , (void *) &addr,sizeof(addr) ) == -1)
     		fatal (" Error in bind: %s\n", strerror (errno) );
     		
        len_r = sizeof(addr);
        imr.imr_multiaddr.s_addr = inet_addr(GROUP),
        imr.imr_interface.s_addr = htonl(INADDR_ANY);

	if ( setsockopt ( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq)) == -1 )
     		fatal ("Error in setsockopt: %s\n", strerror (errno));
                
        while( 1 )
        {
        	if((  cnt = recvfrom( sockfd, recvbuf, sizeof(recvbuf), 0,(void *) &addr, &len_r)) == -1 )
                	fatal ("Error in recvfrom: %s\n", strerror (errno));
                	
                recvbuf[cnt] = 0;
                buf = (char *) malloc(cnt);
                memset(buf, 0, cnt);
                memcpy(buf, recvbuf, cnt);
                tpool_add_work(fnDecodepool, fnDecodeStep1, buf );
        }
}

static void
h_watchdog()
{
        int status;
        if( fork())
        {
                while( 1 ) 
                {
                        if ( (wait(&status) ) < 0 ) 
                        {
                                daemon_init();
                                break;
                        }
                        sleep(1);
                }
        }
        else h_read();
}

static void 
daemon_init()
{
        chdir("/");
        umask(0);
        setsid();
        signal( SIGCHLD, h_watchdog );
        h_watchdog();
}

int main()
{
        daemon_init(); 
        return 0;
}